package com.xj.router;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Author: xiajun
 * Date: 2014-08-25
 * Time: 13:54:00
 * 权重轮询调度算法
 */
public class RoundRobin {
    private int maxWeight = Integer.MIN_VALUE;//最大权重
    private int gcd = Integer.MIN_VALUE;//最大公约数
    private int cw;//当前权重
    private int i = -1;

    public int router(List<Integer> sw) {
        while (true) {
            i = (i + 1) % sw.size();
            if (i == 0) {
                if (gcd == Integer.MIN_VALUE) {
                    gcd = gcd(sw);
                }
                cw = cw - gcd;
                if (cw <= 0) {
                    if (maxWeight == Integer.MIN_VALUE) {
                        maxWeight = getMaxWeight(sw);
                    }
                    cw = maxWeight;
                    if (cw == 0) {
                        return -1;
                    }
                }
            }
            if (sw.get(i) >= cw) {
                return sw.get(i);
            }
        }
    }

    private int getMaxWeight(List<Integer> sw) {
        int max = Integer.MIN_VALUE;
        for (Integer integer : sw) {
            if (integer > max) {
                max = integer;
            }
        }
        return max;
    }

    /**
     * 将map的值转存list
     *
     * @param sw
     * @return
     */
    private List<Integer> mapValue2List(Map<Integer, Integer> sw) {
        if (sw == null || sw.size() == 0) {
            return null;
        }
        List<Integer> list = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : sw.entrySet()) {
            list.add(entry.getValue());
        }
        return list;
    }

    private int gcd(List<Integer> serverWeight) {
        if (serverWeight == null || serverWeight.isEmpty()) {
            return -1;
        }
        int cu = serverWeight.get(0);
        for (int i = 1; i < serverWeight.size(); i++) {
            cu = gcd_(cu, serverWeight.get(i));
        }
        return cu;
    }

    /**
     * 计算2个数之间的最大公约数
     *
     * @param i
     * @param j
     * @return
     */
    private int gcd_(int i, int j) {
        while (i % j != 0) {
            int temp = i % j;
            i = j;
            j = temp;
        }
        return j;
    }

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(7100);
        list.add(1200);
        list.add(1100);
        list.add(600);
        RoundRobin r=new RoundRobin();
        int _25=0,_70=0,_10=0,_5=0;
        for(int i=0;i<100;i++){
            int s= r.router(list);
            if(s==7100){
                _70++;
            }else if(s==1200){
                _25++;
            }else if(s==1100){
                _10++;
            }else if(s==600){
                _5++;
            }
                System.out.println(s);

        }
        System.out.println("70="+_70+"  25="+_25+" 10="+_10+" 5="+_5);
    }
}
